#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Flask群晖API应用
提供Web界面来访问群晖NAS系统
"""

from flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_from_directory
from flask_cors import CORS
from flask_login import LoginManager, login_user, logout_user, login_required, current_user
import requests
import json
from datetime import datetime
import os

# 导入数据库模型
from models import db, AdminUser, BackgroundConfig, init_db

app = Flask(__name__)
app.secret_key = 'synology_flask_secret_key_2024'

# 配置数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///admin.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'admin_index'
login_manager.login_message = '请先登录管理后台'

@login_manager.user_loader
def load_user(user_id):
    return AdminUser.query.get(int(user_id))

@login_manager.unauthorized_handler
def unauthorized():
    # 如果是API请求，返回JSON错误
    if request.path.startswith('/api/'):
        return jsonify({
            'success': False,
            'message': '未登录或登录已过期',
            'error': 'unauthorized'
        }), 401
    # 否则重定向到管理后台页面
    return redirect(url_for('admin_index'))

# 配置CORS
CORS(app, origins=['*'], supports_credentials=True)

# 导入配置文件
try:
    from config import SYNOLOGY_CONFIG, DIAGNOSTIC_CONFIG
    print(f"✅ 已加载配置文件，群晖服务器: {SYNOLOGY_CONFIG['host']}:{SYNOLOGY_CONFIG['port']}")
except ImportError:
    print("❌ 未找到config.py配置文件，使用默认配置")
    SYNOLOGY_CONFIG = {
        'host': '192.168.1.100',
        'port': 5000,
        'username': 'deltawind',
        'password': 'Zy7G2lLU',
        'timeout': 30,
        'use_https': False
    }
    DIAGNOSTIC_CONFIG = {
        'ping_timeout': 5,
        'port_check_timeout': 10
    }

class SynologyAPI:
    def __init__(self, host, port, username, password, timeout=30, use_https=False):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.timeout = timeout
        protocol = 'https' if use_https else 'http'
        self.base_url = f"{protocol}://{host}:{port}"
        self.session = requests.Session()  # 使用session来管理cookie
        self.session.timeout = timeout
    
    def diagnose_network(self):
        """
        网络诊断功能
        """
        import socket
        import subprocess
        import platform
        
        print(f"🔍 开始网络诊断: {self.host}:{self.port}")
        
        # 1. Ping测试
        try:
            if platform.system().lower() == 'windows':
                result = subprocess.run(['ping', '-n', '1', self.host], 
                                      capture_output=True, text=True, timeout=DIAGNOSTIC_CONFIG['ping_timeout'])
            else:
                result = subprocess.run(['ping', '-c', '1', self.host], 
                                      capture_output=True, text=True, timeout=DIAGNOSTIC_CONFIG['ping_timeout'])
            
            if result.returncode == 0:
                print(f"✅ Ping测试成功: {self.host} 可达")
            else:
                print(f"❌ Ping测试失败: {self.host} 不可达")
                return False
        except Exception as e:
            print(f"⚠️ Ping测试异常: {e}")
        
        # 2. 端口连通性测试
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(DIAGNOSTIC_CONFIG['port_check_timeout'])
            result = sock.connect_ex((self.host, self.port))
            sock.close()
            
            if result == 0:
                print(f"✅ 端口测试成功: {self.host}:{self.port} 可连接")
                return True
            else:
                print(f"❌ 端口测试失败: {self.host}:{self.port} 不可连接")
                return False
        except Exception as e:
            print(f"❌ 端口测试异常: {e}")
            return False
    
    def login(self):
        """
        群晖登录API - 使用Cookie认证
        """
        url = f"{self.base_url}/webapi/entry.cgi"
        params = {
            'api': 'SYNO.API.Auth',
            'version': '6',
            'method': 'login',
            'account': self.username,
            'passwd': self.password,
            'session': 'FileStation',
            'format': 'cookie'  # 使用cookie格式
        }
        
        try:
            response = self.session.get(url, params=params, timeout=self.timeout)
            data = response.json()
            
            if data.get('success'):
                return {
                    'success': True,
                    'cookies': dict(self.session.cookies),
                    'message': '登录成功'
                }
            else:
                error_code = data.get('error', {}).get('code', '未知错误')
                return {
                    'success': False,
                    'error_code': error_code,
                    'message': f'登录失败，错误代码: {error_code}'
                }
        except Exception as e:
            print(f"\n❌ 连接群晖失败: {str(e)}")
            print("🔧 开始网络诊断...")
            
            # 进行网络诊断
            network_ok = self.diagnose_network()
            
            if not network_ok:
                error_msg = f"网络连接失败: {str(e)}\n\n" + \
                           f"请检查以下配置:\n" + \
                           f"1. 群晖NAS IP地址是否正确: {self.host}\n" + \
                           f"2. 群晖NAS端口是否正确: {self.port}\n" + \
                           f"3. 网络是否连通\n" + \
                           f"4. 群晖DSM是否正常运行\n\n" + \
                           f"💡 提示: 请修改config.py中的配置"
            else:
                error_msg = f"网络连接正常，但登录失败: {str(e)}\n" + \
                           f"请检查用户名和密码是否正确"
            
            return {
                'success': False,
                'message': error_msg
            }
    
    def list_shares(self, ensure_login=True):
        """
        获取共享文件夹列表 - 使用Cookie认证
        """
        # 如果需要确保登录状态
        if ensure_login:
            login_result = self.login()
            if not login_result['success']:
                return login_result
        
        url = f"{self.base_url}/webapi/entry.cgi"
        params = {
            'api': 'SYNO.FileStation.List',
            'version': '2',
            'method': 'list_share',
            'additional': '["real_path","owner","time"]'
        }
        
        try:
            response = self.session.get(url, params=params, timeout=10)
            data = response.json()
            
            if data.get('success'):
                shares = data['data']['shares']
                # 格式化共享文件夹信息
                formatted_shares = []
                for share in shares:
                    # 处理additional信息
                    additional = share.get('additional', {})
                    owner_info = additional.get('owner', {})
                    time_info = additional.get('time', {})
                    
                    formatted_share = {
                        'name': share.get('name', ''),
                        'path': share.get('path', ''),
                        'isdir': share.get('isdir', True),
                        'size': '共享文件夹',
                        'owner': owner_info.get('user', '系统'),
                        'mtime': self.format_time(time_info.get('mtime', 0)),
                        'real_path': additional.get('real_path', share.get('path', ''))
                    }
                    formatted_shares.append(formatted_share)
                
                return {
                    'success': True,
                    'shares': formatted_shares,
                    'count': len(formatted_shares),
                    'total': data['data'].get('total', len(formatted_shares)),
                    'cookies': dict(self.session.cookies)
                }
            else:
                error_code = data.get('error', {}).get('code')
                if error_code == 119:  # 会话超时，尝试重新登录
                    login_result = self.login()
                    if login_result['success']:
                        # 递归调用，但不再重复登录
                        return self.list_shares(ensure_login=False)
                    else:
                        return login_result
                
                error_messages = {
                    119: '会话超时或权限不足',
                    400: '无效的参数',
                    401: '账号或密码错误',
                    402: '权限被拒绝'
                }
                message = error_messages.get(error_code, f'未知错误代码: {error_code}')
                
                return {
                    'success': False,
                    'error_code': error_code,
                    'message': message
                }
        except Exception as e:
            return {
                'success': False,
                'message': f'请求失败: {str(e)}'
            }
    
    def get_thumbnail(self, file_path, size='small'):
        """
        获取文件缩略图
        """
        url = f"{self.base_url}/webapi/entry.cgi"
        params = {
            'api': 'SYNO.FileStation.Thumb',
            'version': '2',
            'method': 'get',
            'path': file_path,
            'size': size  # small, medium, large
        }
        
        try:
            response = self.session.get(url, params=params, timeout=30)
            if response.status_code == 200 and response.headers.get('content-type', '').startswith('image/'):
                return {
                    'success': True,
                    'content': response.content,
                    'content_type': response.headers.get('content-type')
                }
            else:
                return {
                    'success': False,
                    'message': '无法获取缩略图'
                }
        except Exception as e:
            return {
                'success': False,
                'message': f'请求失败: {str(e)}'
            }
    
    def list_files(self, folder_path='/', ensure_login=True):
        """
        获取文件列表 - 使用Cookie认证
        """
        # 如果需要确保登录状态
        if ensure_login:
            login_result = self.login()
            if not login_result['success']:
                return login_result
        
        url = f"{self.base_url}/webapi/entry.cgi"
        params = {
            'api': 'SYNO.FileStation.List',
            'version': '2',
            'method': 'list',
            'folder_path': folder_path,
            'additional': '["real_path","size","time","perm","type"]'
        }
        
        try:
            response = self.session.get(url, params=params, timeout=10)
            data = response.json()
            
            if data.get('success'):
                files = data['data']['files']
                # 格式化文件信息
                formatted_files = []
                for file in files:
                    additional = file.get('additional', {})
                    time_info = additional.get('time', {})
                    
                    formatted_file = {
                        'name': file.get('name', ''),
                        'path': file.get('path', ''),
                        'isdir': file.get('isdir', False),
                        'size': self.format_file_size(additional.get('size', 0)) if not file.get('isdir', False) else '文件夹',
                        'mtime': self.format_time(time_info.get('mtime', 0)),
                        'mtime_timestamp': time_info.get('mtime', 0),  # 保留原始时间戳用于排序
                        'real_path': additional.get('real_path', file.get('path', ''))
                    }
                    formatted_files.append(formatted_file)
                
                return {
                    'success': True,
                    'files': formatted_files,
                    'count': len(formatted_files),
                    'path': folder_path,
                    'cookies': dict(self.session.cookies)
                }
            else:
                error_code = data.get('error', {}).get('code')
                if error_code == 119:  # 会话超时，尝试重新登录
                    login_result = self.login()
                    if login_result['success']:
                        # 递归调用，但不再重复登录
                        return self.list_files(folder_path, ensure_login=False)
                    else:
                        return login_result
                
                error_messages = {
                    119: '会话超时或权限不足',
                    400: '无效的参数',
                    401: '账号或密码错误',
                    402: '权限被拒绝'
                }
                message = error_messages.get(error_code, f'未知错误代码: {error_code}')
                
                return {
                    'success': False,
                    'error_code': error_code,
                    'message': message
                }
        except Exception as e:
            return {
                'success': False,
                'message': f'请求失败: {str(e)}'
            }
    
    def format_file_size(self, size_bytes):
        """
        格式化文件大小
        """
        if size_bytes == 0:
            return "0 B"
        
        size_names = ["B", "KB", "MB", "GB", "TB"]
        import math
        i = int(math.floor(math.log(size_bytes, 1024)))
        p = math.pow(1024, i)
        s = round(size_bytes / p, 2)
        return f"{s} {size_names[i]}"
    
    def format_time(self, timestamp):
        """
        格式化时间戳
        """
        if timestamp:
            return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
        return '未知'
    
    def upload_file(self, file_data, filename, destination_path, create_parents=True, overwrite=False):
        """
        上传文件到群晖NAS
        根据群晖FileStation API文档实现
        """
        # 确保登录状态
        login_result = self.login()
        if not login_result['success']:
            return login_result
        
        url = f"{self.base_url}/webapi/entry.cgi"
        
        # 准备multipart/form-data数据
        files = {
            'file': (filename, file_data, 'application/octet-stream')
        }
        
        data = {
            'api': 'SYNO.FileStation.Upload',
            'version': '2',
            'method': 'upload',
            'path': destination_path,
            'create_parents': 'true' if create_parents else 'false',
            'overwrite': 'true' if overwrite else 'false'
        }
        
        try:
            response = self.session.post(url, data=data, files=files, timeout=self.timeout)
            response_data = response.json()
            
            if response_data.get('success'):
                return {
                    'success': True,
                    'message': '文件上传成功',
                    'filename': filename,
                    'path': destination_path
                }
            else:
                error_code = response_data.get('error', {}).get('code')
                error_messages = {
                    1800: 'HTTP头中缺少Content-Length信息或接收大小与Content-Length不匹配',
                    1801: '等待时间过长，无法从客户端接收数据',
                    1802: '文件内容最后部分缺少文件名信息',
                    1803: '上传连接被取消',
                    1804: '无法上传超大文件到FAT文件系统',
                    1805: '无法覆盖或跳过现有文件，未提供overwrite参数'
                }
                
                error_msg = error_messages.get(error_code, f'上传失败，错误代码: {error_code}')
                return {
                    'success': False,
                    'message': error_msg,
                    'error_code': error_code
                }
                
        except requests.exceptions.Timeout:
            return {
                'success': False,
                'message': '上传请求超时'
            }
        except Exception as e:
            return {
                'success': False,
                'message': f'上传请求失败: {str(e)}'
            }

# 创建API实例
synology_api = SynologyAPI(
    SYNOLOGY_CONFIG['host'],
    SYNOLOGY_CONFIG['port'],
    SYNOLOGY_CONFIG['username'],
    SYNOLOGY_CONFIG['password'],
    SYNOLOGY_CONFIG['timeout'],
    SYNOLOGY_CONFIG['use_https']
)

@app.route('/')
def index():
    """
    React图片浏览器主页
    """
    return render_template('frontend/build/index.html')

@app.route('/static/css/<filename>')
def react_css(filename):
    """
    服务React CSS文件
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build/static/css', filename)

@app.route('/static/js/<filename>')
def react_js(filename):
    """
    服务React JS文件
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build/static/js', filename)

@app.route('/static/<path:filename>')
def react_static(filename):
    """
    服务React其他静态文件
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build/static', filename)

@app.route('/manifest.json')
def manifest():
    """
    服务React manifest.json
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build', 'manifest.json')

@app.route('/favicon.ico')
def favicon():
    """
    服务React favicon
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build', 'favicon.ico')

@app.route('/logo192.png')
def logo192():
    """
    服务React logo192
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build', 'logo192.png')

@app.route('/logo512.png')
def logo512():
    """
    服务React logo512
    """
    from flask import send_from_directory
    return send_from_directory('templates/frontend/build', 'logo512.png')

@app.route('/api/login', methods=['POST'])
def api_login():
    """
    登录API接口
    """
    result = synology_api.login()
    
    if result['success']:
        session['cookies'] = result['cookies']
        session['logged_in'] = True
    
    return jsonify(result)

@app.route('/api/shares', methods=['GET'])
def api_shares():
    """
    获取共享文件夹列表API接口
    """
    # 使用Cookie认证，自动处理登录
    result = synology_api.list_shares()
    
    # 如果成功，更新会话状态
    if result.get('success'):
        session['logged_in'] = True
        session['cookies'] = result.get('cookies', {})
    
    return jsonify(result)

@app.route('/api/files', methods=['GET'])
def api_files():
    """
    获取文件列表API接口
    """
    folder_path = request.args.get('path', '/')
    result = synology_api.list_files(folder_path)
    
    # 如果成功，更新会话状态
    if result.get('success'):
        session['logged_in'] = True
        session['cookies'] = result.get('cookies', {})
    
    return jsonify(result)

@app.route('/api/thumbnail')
def api_thumbnail():
    """
    获取文件缩略图API接口
    """
    file_path = request.args.get('path')
    size = request.args.get('size', 'small')
    
    if not file_path:
        return jsonify({
            'success': False,
            'message': '缺少文件路径参数'
        })
    
    result = synology_api.get_thumbnail(file_path, size)
    
    if result['success']:
        from flask import Response
        return Response(
            result['content'],
            mimetype=result['content_type'],
            headers={'Cache-Control': 'public, max-age=3600'}
        )
    else:
        return jsonify(result), 404

@app.route('/api/ftpdata-folders')
def api_ftpdata_folders():
    """
    获取FtpData下的文件夹列表（过滤系统文件夹）
    """
    result = synology_api.list_files('/FtpData')
    
    if result['success']:
        # 过滤出文件夹，排除系统文件夹
        system_folders = {'.Recycle_bin', '.@__thumb', '@eaDir', '#recycle', '.DS_Store'}
        folders = [
            folder for folder in result['files']
            if folder['isdir'] and folder['name'] not in system_folders and not folder['name'].startswith('.')
        ]
        
        return jsonify({
            'success': True,
            'folders': folders,
            'count': len(folders)
        })
    else:
        return jsonify(result)

@app.route('/api/images')
def api_images():
    """
    获取指定文件夹下的图片文件
    """
    folder_path = request.args.get('path', '/FtpData')
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 20))
    sort_by = request.args.get('sort_by', 'time')  # 默认按时间排序
    sort_order = request.args.get('sort_order', 'desc')  # 默认降序（最新的在前）
    
    result = synology_api.list_files(folder_path)
    
    if result['success']:
        # 过滤出图片文件
        image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.svg'}
        images = [
            file for file in result['files']
            if not file['isdir'] and any(file['name'].lower().endswith(ext) for ext in image_extensions)
        ]
        
        # 按时间或名称排序
        if sort_by == 'time':
            # 使用原始时间戳进行排序
            if sort_order == 'desc':
                images.sort(key=lambda x: x.get('mtime_timestamp', 0), reverse=True)
            else:
                images.sort(key=lambda x: x.get('mtime_timestamp', 0))
        elif sort_by == 'name':
            if sort_order == 'desc':
                images.sort(key=lambda x: x['name'], reverse=True)
            else:
                images.sort(key=lambda x: x['name'])
        
        # 分页处理
        total = len(images)
        start = (page - 1) * per_page
        end = start + per_page
        paginated_images = images[start:end]
        
        return jsonify({
            'success': True,
            'images': paginated_images,
            'pagination': {
                'page': page,
                'per_page': per_page,
                'total': total,
                'pages': (total + per_page - 1) // per_page
            }
        })
    else:
        return jsonify(result)

@app.route('/api/download')
def api_download():
    """
    文件下载API接口 - 通过Flask代理下载
    """
    file_path = request.args.get('path')
    
    if not file_path:
        return jsonify({
            'success': False,
            'message': '缺少文件路径参数'
        }), 400
    
    # 确保登录状态
    login_result = synology_api.login()
    if not login_result['success']:
        return jsonify({
            'success': False,
            'message': '登录失败，无法下载文件'
        }), 401
    
    # 构建群晖下载URL
    download_url = f"{synology_api.base_url}/webapi/entry.cgi"
    params = {
        'api': 'SYNO.FileStation.Download',
        'version': '2',
        'method': 'download',
        'path': f'["{file_path}"]',
        'mode': 'download'
    }
    
    try:
        # 使用session发送请求（携带Cookie）
        response = synology_api.session.get(download_url, params=params, stream=True, timeout=30)
        
        if response.status_code == 200:
            # 获取文件名
            import os
            filename = os.path.basename(file_path)
            
            # 创建Flask响应
            from flask import Response
            def generate():
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        yield chunk
            
            flask_response = Response(
                generate(),
                mimetype=response.headers.get('content-type', 'application/octet-stream')
            )
            
            # 设置下载头
            flask_response.headers['Content-Disposition'] = f'attachment; filename="{filename}"'
            flask_response.headers['Content-Length'] = response.headers.get('content-length', '')
            
            return flask_response
        else:
            return jsonify({
                'success': False,
                'message': f'下载失败，状态码: {response.status_code}'
            }), response.status_code
            
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'下载请求失败: {str(e)}'
        }), 500

@app.route('/api/qrcode')
def api_qrcode():
    """
    生成二维码API接口
    """
    data = request.args.get('data')
    size = int(request.args.get('size', 200))
    
    if not data:
        return jsonify({
            'success': False,
            'message': '缺少二维码数据参数'
        }), 400
    
    try:
        import qrcode
        from qrcode.image.pil import PilImage
        from io import BytesIO
        from flask import Response
        import traceback
        
        print(f"Generating QR code for data: {data[:100]}...")  # Debug log
        
        # 把data中的 http://202.130.187.101:5001 替换为 https://eudxuphalugb.sealoshzh.site

        data = data.replace('http://202.130.187.101:5001', 'https://eudxuphalugb.sealoshzh.site')

        # 创建二维码
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data(data)
        qr.make(fit=True)
        
        # 生成图片
        img = qr.make_image(fill_color="black", back_color="white")
        
        # 调整大小
        img = img.resize((size, size))
        
        # 转换为字节流
        img_io = BytesIO()
        img.save(img_io, 'PNG')
        img_io.seek(0)
        
        print(f"QR code generated successfully, size: {len(img_io.getvalue())} bytes")  # Debug log
        
        return Response(
            img_io.getvalue(),
            mimetype='image/png',
            headers={'Cache-Control': 'public, max-age=3600'}
        )
        
    except ImportError as e:
        error_msg = f'缺少qrcode库: {str(e)}，请安装: pip install qrcode[pil]'
        print(f"Import error: {error_msg}")
        return jsonify({
            'success': False,
            'message': error_msg
        }), 500
    except Exception as e:
        error_msg = f'生成二维码失败: {str(e)}'
        print(f"QR code generation error: {error_msg}")
        print(f"Traceback: {traceback.format_exc()}")
        return jsonify({
            'success': False,
            'message': error_msg
        }), 500

@app.route('/api/delete', methods=['POST'])
def api_delete():
    """
    删除文件API接口
    """
    file_path = request.json.get('path') if request.json else None
    
    if not file_path:
        return jsonify({
            'success': False,
            'message': '缺少文件路径参数'
        }), 400
    
    # 确保登录状态
    login_result = synology_api.login()
    if not login_result['success']:
        return jsonify({
            'success': False,
            'message': '登录失败，无法删除文件'
        }), 401
    
    # 构建群晖删除URL
    delete_url = f"{synology_api.base_url}/webapi/entry.cgi"
    params = {
        'api': 'SYNO.FileStation.Delete',
        'version': '2',
        'method': 'delete',
        'path': f'["{file_path}"]'
    }
    
    try:
        # 使用session发送请求（携带Cookie）
        response = synology_api.session.post(delete_url, data=params, timeout=30)
        data = response.json()
        
        if data.get('success'):
            return jsonify({
                'success': True,
                'message': '文件删除成功'
            })
        else:
            error_code = data.get('error', {}).get('code')
            error_messages = {
                119: '会话超时或权限不足',
                400: '无效的参数',
                401: '账号或密码错误',
                402: '权限被拒绝',
                408: '文件不存在',
                409: '文件正在使用中'
            }
            message = error_messages.get(error_code, f'删除失败，错误代码: {error_code}')
            
            return jsonify({
                'success': False,
                'message': message
            }), 400
            
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'删除请求失败: {str(e)}'
        }), 500

@app.route('/api/upload', methods=['POST'])
def api_upload():
    """
    文件上传API接口
    """
    try:
        # 检查是否有文件
        if 'file' not in request.files:
            return jsonify({'success': False, 'message': '没有选择文件'}), 400
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'success': False, 'message': '没有选择文件'}), 400
        
        # 获取其他参数
        destination_path = request.form.get('path')
        create_parents = request.form.get('create_parents', 'true').lower() == 'true'
        overwrite = request.form.get('overwrite', 'false').lower() == 'true'
        
        if not destination_path:
            return jsonify({'success': False, 'message': '缺少目标路径参数'}), 400
        
        # 读取文件数据
        file_data = file.read()
        filename = file.filename
        
        # 上传文件
        result = synology_api.upload_file(
            file_data=file_data,
            filename=filename,
            destination_path=destination_path,
            create_parents=create_parents,
            overwrite=overwrite
        )
        
        if result['success']:
            return jsonify(result)
        else:
            return jsonify(result), 500
            
    except Exception as e:
        return jsonify({'success': False, 'message': f'上传失败: {str(e)}'}), 500

@app.route('/api/diagnose', methods=['GET'])
def api_diagnose():
    """
    网络诊断API接口
    """
    try:
        # 进行网络诊断
        network_ok = synology_api.diagnose_network()
        
        return jsonify({
            'success': True,
            'network_ok': network_ok,
            'config': {
                'host': SYNOLOGY_CONFIG['host'],
                'port': SYNOLOGY_CONFIG['port'],
                'timeout': SYNOLOGY_CONFIG['timeout']
            },
            'message': '网络诊断完成，请查看控制台输出'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'诊断失败: {str(e)}'
        }), 500

@app.route('/api/logout', methods=['POST'])
def api_logout():
    """
    登出API接口
    """
    session.clear()
    return jsonify({
        'success': True,
        'message': '已登出'
    })

@app.route('/files')
def files_page():
    """
    文件浏览页面（已废弃，使用React前端）
    """
    return redirect('/')

# ==================== 管理后台相关路由 ====================

@app.route('/admin')
@app.route('/admin/')
@app.route('/admin/<path:path>')
def admin_index(path=None):
    """
    管理后台页面 - 返回React应用
    """
    return render_template('frontend/build/index.html')



@app.route('/api/admin/login', methods=['POST'])
def api_admin_login():
    """
    管理后台登录API
    """
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    
    if not username or not password:
        return jsonify({
            'success': False,
            'message': '用户名和密码不能为空'
        }), 400
    
    user = AdminUser.query.filter_by(username=username).first()
    
    if user and user.check_password(password) and user.is_active:
        login_user(user)
        user.last_login = datetime.utcnow()
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '登录成功',
            'user': user.to_dict()
        })
    else:
        return jsonify({
            'success': False,
            'message': '用户名或密码错误'
        }), 401

@app.route('/api/admin/logout', methods=['POST'])
@login_required
def api_admin_logout():
    """
    管理后台登出API
    """
    logout_user()
    return jsonify({
        'success': True,
        'message': '已登出'
    })

@app.route('/api/admin/current-user')
@login_required
def api_admin_current_user():
    """
    获取当前登录用户信息
    """
    return jsonify({
        'success': True,
        'user': current_user.to_dict()
    })

@app.route('/api/admin/users')
@login_required
def api_admin_users():
    """
    获取用户列表
    """
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    
    users = AdminUser.query.paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    return jsonify({
        'success': True,
        'users': [user.to_dict() for user in users.items],
        'pagination': {
            'page': page,
            'per_page': per_page,
            'total': users.total,
            'pages': users.pages
        }
    })

@app.route('/api/admin/users', methods=['POST'])
@login_required
def api_admin_create_user():
    """
    创建新用户
    """
    data = request.get_json()
    username = data.get('username')
    email = data.get('email')
    password = data.get('password')
    is_superuser = data.get('is_superuser', False)
    
    if not username or not email or not password:
        return jsonify({
            'success': False,
            'message': '用户名、邮箱和密码不能为空'
        }), 400
    
    # 检查用户名是否已存在
    if AdminUser.query.filter_by(username=username).first():
        return jsonify({
            'success': False,
            'message': '用户名已存在'
        }), 400
    
    # 检查邮箱是否已存在
    if AdminUser.query.filter_by(email=email).first():
        return jsonify({
            'success': False,
            'message': '邮箱已存在'
        }), 400
    
    try:
        user = AdminUser(
            username=username,
            email=email,
            is_superuser=is_superuser
        )
        user.set_password(password)
        
        db.session.add(user)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '用户创建成功',
            'user': user.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'创建用户失败: {str(e)}'
        }), 500

@app.route('/api/admin/users/<int:user_id>', methods=['PUT'])
@login_required
def api_admin_update_user(user_id):
    """
    更新用户信息
    """
    user = AdminUser.query.get_or_404(user_id)
    data = request.get_json()
    
    try:
        if 'username' in data:
            # 检查用户名是否已被其他用户使用
            existing_user = AdminUser.query.filter_by(username=data['username']).first()
            if existing_user and existing_user.id != user_id:
                return jsonify({
                    'success': False,
                    'message': '用户名已存在'
                }), 400
            user.username = data['username']
        
        if 'email' in data:
            # 检查邮箱是否已被其他用户使用
            existing_user = AdminUser.query.filter_by(email=data['email']).first()
            if existing_user and existing_user.id != user_id:
                return jsonify({
                    'success': False,
                    'message': '邮箱已存在'
                }), 400
            user.email = data['email']
        
        if 'password' in data and data['password']:
            user.set_password(data['password'])
        
        if 'is_active' in data:
            user.is_active = data['is_active']
        
        if 'is_superuser' in data:
            user.is_superuser = data['is_superuser']
        
        user.updated_at = datetime.utcnow()
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '用户更新成功',
            'user': user.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'更新用户失败: {str(e)}'
        }), 500

@app.route('/api/admin/users/<int:user_id>', methods=['DELETE'])
@login_required
def api_admin_delete_user(user_id):
    """
    删除用户
    """
    user = AdminUser.query.get_or_404(user_id)
    
    # 不能删除自己
    if user.id == current_user.id:
        return jsonify({
            'success': False,
            'message': '不能删除自己的账户'
        }), 400
    
    # 不能删除超级管理员
    if user.is_superuser:
        return jsonify({
            'success': False,
            'message': '不能删除超级管理员账户'
        }), 400
    
    try:
        db.session.delete(user)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '用户删除成功'
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'删除用户失败: {str(e)}'
        }), 500

# 背景图片配置API
@app.route('/api/admin/background-config', methods=['GET'])
@login_required
def api_admin_get_background_config():
    """获取背景图片配置"""
    try:
        configs = BackgroundConfig.query.all()
        config_list = [config.to_dict() for config in configs]
        
        return jsonify({
            'success': True,
            'data': config_list
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'获取背景配置失败: {str(e)}'
        }), 500

@app.route('/api/admin/background-config', methods=['POST'])
@login_required
def api_admin_upload_background_config():
    """上传背景图片配置"""
    try:
        if 'file' not in request.files:
            return jsonify({
                'success': False,
                'message': '未找到上传文件'
            }), 400
        
        file = request.files['file']
        config_type = request.form.get('config_type')  # 'header' 或 'background'
        
        if not file or file.filename == '':
            return jsonify({
                'success': False,
                'message': '未选择文件'
            }), 400
        
        if config_type not in ['header', 'background']:
            return jsonify({
                'success': False,
                'message': '配置类型必须是 header 或 background'
            }), 400
        
        # 检查文件类型
        if not file.content_type.startswith('image/'):
            return jsonify({
                'success': False,
                'message': '只能上传图片文件'
            }), 400
        
        # 保存文件到本地服务器
        import uuid
        import os
        
        # 创建本地存储目录
        upload_dir = os.path.join(os.path.dirname(__file__), 'uploads', 'backgrounds')
        os.makedirs(upload_dir, exist_ok=True)
        
        # 生成唯一文件名
        file_extension = os.path.splitext(file.filename)[1]
        unique_filename = f"{uuid.uuid4()}{file_extension}"
        file_path = os.path.join(upload_dir, unique_filename)
        
        # 保存文件
        file.save(file_path)
        
        # 构建图片URL
        image_url = f'/uploads/backgrounds/{unique_filename}'
        
        # 更新数据库配置
        # 先将同类型的旧配置设为非活跃
        BackgroundConfig.query.filter_by(config_type=config_type, is_active=True).update({'is_active': False})
        
        # 创建新配置
        new_config = BackgroundConfig(
            config_type=config_type,
            image_url=image_url,
            image_filename=file.filename
        )
        
        db.session.add(new_config)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '背景图片上传成功',
            'data': new_config.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'上传背景图片失败: {str(e)}'
        }), 500

# 静态文件服务路由 - 用于访问上传的背景图片
@app.route('/uploads/<path:filename>')
def uploaded_file(filename):
    """提供上传文件的静态访问"""
    try:
        upload_dir = os.path.join(os.path.dirname(__file__), 'uploads')
        return send_from_directory(upload_dir, filename)
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'文件不存在: {str(e)}'
        }), 404

@app.route('/api/admin/background-config/<int:config_id>', methods=['DELETE'])
@login_required
def api_admin_delete_background_config(config_id):
    """删除背景图片配置"""
    try:
        config = BackgroundConfig.query.get(config_id)
        if not config:
            return jsonify({
                'success': False,
                'message': '配置不存在'
            }), 404
        
        # 从数据库中真正删除记录
        db.session.delete(config)
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '背景图片配置已删除'
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'删除背景配置失败: {str(e)}'
        }), 500

# 重新激活背景配置API
@app.route('/api/admin/background-config/<int:config_id>/activate', methods=['POST'])
@login_required
def api_admin_activate_background_config(config_id):
    """重新激活背景图片配置"""
    try:
        config = BackgroundConfig.query.get(config_id)
        if not config:
            return jsonify({
                'success': False,
                'message': '配置不存在'
            }), 404
        
        # 先将同类型的旧配置设为非活跃
        BackgroundConfig.query.filter_by(config_type=config.config_type, is_active=True).update({'is_active': False})
        
        # 将当前配置设为活跃
        config.is_active = True
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': '背景图片配置已激活'
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'message': f'激活背景配置失败: {str(e)}'
        }), 500

# 客户端获取背景配置API（无需登录）
@app.route('/api/background-config', methods=['GET'])
def api_get_background_config():
    """客户端获取背景图片配置"""
    try:
        configs = BackgroundConfig.query.filter_by(is_active=True).all()
        config_list = []
        for config in configs:
            config_list.append({
                'config_type': config.config_type,
                'image_url': config.image_url,
                'is_active': config.is_active,
                'updated_at': config.updated_at.isoformat() if config.updated_at else None
            })
        
        return jsonify({
            'success': True,
            'data': config_list
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'获取背景配置失败: {str(e)}'
        }), 500

if __name__ == '__main__':
    # 初始化数据库
    init_db(app)
    
    print("🚀 启动Flask群晖API应用")
    print(f"📡 群晖服务器: {SYNOLOGY_CONFIG['host']}:{SYNOLOGY_CONFIG['port']}")
    print(f"👤 用户名: {SYNOLOGY_CONFIG['username']}")
    print("🌐 访问地址: http://localhost:8080")
    print("🔧 管理后台: http://localhost:8080/admin")
    print("-" * 50)

    app.run(debug=True, host='0.0.0.0', port=8080)